package flirtme.fragments;

import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;

import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.ConnectionCreationListener;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.filter.MessageTypeFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.util.StringUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;

import com.ans.flirtme.R;
import com.loopj.android.http.RequestParams;

import flirtme.activities.MainMenuActivity;
import flirtme.adapter.ContactListAdapter;
import flirtme.constants.Constants;
import flirtme.libraries.utils.Utils;
import flirtme.managers.GPSManager;
import flirtme.managers.UserManager;
import flirtme.model.ContactModel;
import flirtme.server.FlirtMeAsyncHttpResponseHandler;
import flirtme.server.FlirtMeRestClient;
import flirtme.tools.ChatConnector;
import flirtme.widgets.NonCancellableProgressDialog;

public class ContactsFragment extends Fragment implements
		ConnectionCreationListener, PacketListener, Observer{
	static ArrayList<ContactModel> contacts = null;
	static ListView lv1;

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		// Inflate the layout for this fragment

		View view = inflater.inflate(R.layout.activity_contacts, container,
				false);

		UserManager um = UserManager.instance();
		um.setShouldShowBroadcastMessages(false);
		if (!um.isConnectedToChat()) {

			ChatConnector ChatConnector = new ChatConnector(this.getActivity(),
					this);
			ChatConnector.connect();
		} else {
			this.addPacketListener(um.getConnection());
		}

		m_handler = new Handler();

		if (contacts == null) {
			contacts = new ArrayList<ContactModel>();
			// stopRepeatingTask();
			// startRepeatingTask();

			getLocation();
		}

		lv1 = (ListView) view.findViewById(R.id.custom_list);

		ContactListAdapter adapter = new ContactListAdapter(this.getActivity(),
				contacts);
		;
		lv1.setAdapter(adapter);

		lv1.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> a, View v, int position,
					long id) {

				removePacketListener();
				ContactModel contact = contacts.get(position);
				Intent intent = new Intent(ContactsFragment.this.getActivity(),
						flirtme.activities.ChatActivity.class);
				intent.putExtra(Constants.USER_NAME, contact.getUsername());
				startActivity(intent);

			}

		});

		return view;
	}

	private int m_interval = Constants.UPDATE_POSITION_REFRESH;
	private Handler m_handler;

	Runnable m_statusChecker = new Runnable() {
		@Override
		public void run() {
			getLocation();
			m_handler.postDelayed(m_statusChecker, m_interval);
		}
	};

	void startRepeatingTask() {
		m_statusChecker.run();
	}

	void stopRepeatingTask() {
		m_handler.removeCallbacks(m_statusChecker);
	}

	@Override
	public void onDestroyView() {
		super.onDestroyView();
		//stopRepeatingTask();
		this.removePacketListener();
		if (!Utils.runningOnSimulator()) {
			GPSManager manager = GPSManager.Instance();
			manager.stopLocationReceiver();
		}
	}

	private void getLocation() {
		if (!Utils.runningOnSimulator()) {
			GPSManager manager = GPSManager.Instance();
			if (manager.getCurrentLocation() == null) {
				manager.addObserver(this);
				manager.startLocationReceiver(getActivity());	
			}
			else {
				getContacts(manager.getCurrentLocation());
			}
		}
		else {
			Location loc = new Location("dummyprovider");
			loc.setLatitude(-34.5900825);
			loc.setLongitude(-58.4053955);
			getContacts(loc);
		}
	}
	
	@Override
	public void update(Observable observable, Object data) {
		GPSManager manager = GPSManager.Instance();
		manager.deleteObserver(this);
		Location location = (Location) data;
		if (location != null) {
			getContacts(location);
		}
		
	}
	
	private void getContacts(Location location) {
		
		RequestParams params = getRequestParams(location);
		callService(this.getActivity(), Constants.UPDATE_POSITION_SERVICE,
				params, false);
	}

	private static RequestParams getRequestParams(Location location) {
		String latitude = String.valueOf( location.getLatitude()); 
		String longitude = String.valueOf( location.getLongitude());
		 
		RequestParams params = new RequestParams();
		params.put("latitud", latitude);
		params.put("longitud", longitude);
		params.put("username", UserManager.instance().getUser().getUsername());
		params.put("getNearUsers", "true");
		return params;
	}
	
	public static void refreshContacts(Context  context) {
		
		Location loc = GPSManager.Instance().getCurrentLocation();
		if (loc != null) {
			getContactsForRefresh(loc, context);
		}
		else {
			MainMenuActivity.toastMessageWithText(context, R.string.response_fail_text);
		}
	}
	private static  void getContactsForRefresh(Location location, Context context) {
		RequestParams params = getRequestParams(location);
		callService(context, Constants.UPDATE_POSITION_SERVICE,
				params, true);
	}
	
	
	private static ContactModel getContactModelWithName(String name, ArrayList<ContactModel> array) {
		ContactModel model = null;
		for (ContactModel contactModel : array) {
			if (contactModel.getUsername().equalsIgnoreCase(name)) {
				model = contactModel;
				return model;
			}
		}
		return null;
	}
	private static void callService(final Context context,
			final String serviceName, RequestParams params, final Boolean refresh) {

		FlirtMeRestClient.get(serviceName, params,

		new FlirtMeAsyncHttpResponseHandler(context) {
			NonCancellableProgressDialog dialog = new NonCancellableProgressDialog(
					context);

			@SuppressWarnings("unchecked")
			@Override			
			public void onSuccess(JSONObject response) {
				if (FlirtMeAsyncHttpResponseHandler.isValid(response)) {

					try {

						JSONArray payload = response
								.getJSONArray((Constants.PAYLOAD));

						if (payload != null) {
							int count = payload.length();
						
							ArrayList<ContactModel> copyArray = null;
							if (refresh) {
								// Para mantener el número de mensajes no leidos
								copyArray = (ArrayList<ContactModel>) contacts.clone();
							}
							contacts.clear();
							
							for (int i = 0; i < count; i++) {
								JSONObject object = payload.getJSONObject(i);

								if (object != null) {
									ContactModel model = new ContactModel();
									String username = object
											.getString(Constants.USER_NAME);
									String avatarUrl = FlirtMeRestClient.getFullHttpUrl(object.getString(Constants.AVATAR_URL));		
									String meters = object
											.getString(Constants.METERS);
									String birthDate = object
											.getString(Constants.BIRTH_DATE);
									String age = object
											.getString(Constants.AGE);
									String email = object
											.getString(Constants.EMAIL);
									
									String firstname = object.getString(Constants.FIRST_NAME);
									String lastname = object.getString(Constants.LAST_NAME);
									String interests = object.getString(Constants.INTERESTS);
									String gender = object.getString(Constants.GENDER);
								
									model.setUsername(username);
									model.setEmail(email);
									model.setBirthDate(birthDate);
									model.setAge(age);
									model.setGender(gender);
									model.setDistance(meters);
									model.setImageUrl(avatarUrl);
									model.setFirstname(firstname);
									model.setLastname(lastname);
									model.setInterests(interests);
									
									if (copyArray != null) {
										ContactModel copyModel = getContactModelWithName(username, copyArray);
										model.setNumberOfMessagesNotReaded(copyModel.getNumberOfMessagesNotReaded());
									}
									
									contacts.add(model);
								}
							}
							UserManager.instance().setContacs(contacts);

							((Activity) context).runOnUiThread(new Runnable() {

								@Override
								public void run() {

									ContactListAdapter adapter = (ContactListAdapter) lv1
											.getAdapter();
									adapter.notifyDataSetChanged();
								}
							});

						}

					} catch (JSONException e) {
						e.printStackTrace();
					}

				} else {

				}
			}

			@Override
			public void onFinish() {
				dialog.dismiss();
			}

			@Override
			public void onStart() {
				dialog.setMessage("Scaning for near users");
				dialog.show();

			}
			@Override
			public void onFailure(Throwable e, String response) {
				 MainMenuActivity.toastMessageWithText(context, R.string.response_fail_text);
		  }
		});
	}



	private ArrayList<ContactModel> getListData() {
		ArrayList<ContactModel> results = new ArrayList<ContactModel>();
		ContactModel model = new ContactModel();
		model.setUsername("Analissa Santi");
		model.setEmail("egracielaortiz@gmail.com");
		model.setDistance("21");
		model.setImageUrl("http://www.ciudad.com.ar/sites/default/files/imagecache/cathair-620x380-nocrop/2013/05/13/annalisa_santi_17.jpg.crop_display.jpg");
		results.add(model);

		model = new ContactModel();
		model.setUsername("ramiro1");
		model.setEmail("fran");
		model.setDistance("10");
		model.setImageUrl("http://www.diariouno.com.ar/export/sites/diariouno/imagenes/2011/12/12/PRE-jelinek.jpg_2033098437.jpg");
		results.add(model);

		model = new ContactModel();
		model.setUsername("ramiro2");
		model.setEmail("ramiro.do");
		model.setDistance("4");
		model.setImageUrl("http://sphotos-h.ak.fbcdn.net/hphotos-ak-snc7/407734_393956277340410_1881684765_n.jpg");
		results.add(model);

		model = new ContactModel();
		model.setUsername("Ramiro");
		model.setDistance("1");
		model.setEmail("ramiro.do@gmail.com");
		model.setImageUrl("http://bucket1.clanacion.com.ar/anexos/fotos/93/el-caso-de-lazaro-baez-1695093w300.jpg");
		results.add(model);

		return results;
	}

	@Override
	public void connectionCreated(Connection connection) {
		XMPPConnection.removeConnectionCreationListener(this);
		addPacketListener(connection);
	}

	private void addPacketListener(Connection connection) {
		if (connection != null) {
			// Add a packet listener to get messages sent to us
			PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
			connection.addPacketListener(this, filter);
		}

	}

	private void removePacketListener() {
		XMPPConnection connection = UserManager.instance().getConnection();
		if (connection != null) {
			connection.removePacketListener(this);
		}
	}

	@Override
	public void processPacket(Packet packet) {
		Message message = (Message) packet;
		if (message.getBody() != null) {
			String fromFull = StringUtils.parseBareAddress(message.getFrom());
			String fromName = ChatConnector.getUserNameFromChatEmail(fromFull);

			final ContactModel cm = UserManager.instance().getContact(fromName);
			cm.queueMessage(message);
			cm.incrementNumberOfMessagesNotReaded();

			Runnable run = new Runnable() {
				public void run() {
					ContactListAdapter adapter = (ContactListAdapter) lv1
							.getAdapter();
					adapter.notifyDataSetChanged();
				}
			};
			getActivity().runOnUiThread(run);

		}
	}



}
